package br.uniceub.fsw.agenda.model.dao;

import br.uniceub.fsw.agenda.exception.BusinessException;
import br.uniceub.fsw.agenda.exception.DatabaseException;
import br.uniceub.fsw.agenda.exception.UniqueConstraintException;
import br.uniceub.fsw.agenda.model.vo.TipoLogradouroVO;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Bruno
 */
public class TipoLogradouroDAO extends GenericDAO {

    public TipoLogradouroDAO(Connection con) {
        super(con);
    }
    
    /**
     * Devolve lista com objetos TipoLogradouro ordenados por ordem alfabetica
     * @return
     * @throws BusinessException
     * @throws DatabaseException
     */
    public List<TipoLogradouroVO> findAll() throws BusinessException, DatabaseException {
        //string de consulta
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TT_TIPOLOGRADOURO ORDER BY DS_TIPOLOGRADOURO");
        
        List<TipoLogradouroVO> listaRegistros = new ArrayList<TipoLogradouroVO>();
        
        try {
            //objeto con é herdado da super classe
            Statement st = this.con.createStatement();
            ResultSet rs = st.executeQuery(query.toString());
            while (rs.next()) {
                TipoLogradouroVO tipoLogradouro = new TipoLogradouroVO();
                
                tipoLogradouro.setIdTipoLogradouro(rs.getInt("ID_TIPOLOGRADOURO"));
                tipoLogradouro.setDsTipoLogradouro(rs.getString("DS_TIPOLOGRADOURO"));
                
                listaRegistros.add(tipoLogradouro);
            }
            st.close();
            rs.close();
            return listaRegistros;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro ao buscar tipos de logradouro", ex);
        }        
    }
    
    /**
     * Buscar objeto TipoLogradouro pelo seu id
     * @param idTipoLogradouro código do tipoLogradouro que se deseja buscar
     * @return objeto TipoLogradouro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public TipoLogradouroVO findById(Integer idTipoLogradouro) throws DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TT_TIPOLOGRADOURO WHERE ID_TIPOLOGRADOURO = ?");
        
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, idTipoLogradouro.toString());
            
            ResultSet rs = st.executeQuery();

            TipoLogradouroVO tipoLogradouro = new TipoLogradouroVO();
            
            while (rs.next()) {
                tipoLogradouro.setIdTipoLogradouro(rs.getInt("ID_TIPOLOGRADOURO"));
                tipoLogradouro.setDsTipoLogradouro(rs.getString("DS_TIPOLOGRADOURO"));
            }
            
            st.close();
            rs.close();
            
            return tipoLogradouro;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOTipoLogradouro.findById()", ex);
        }
    }

    /**
     * Buscar lista de tipos de logradouro por parte de seu nome
     * @param dsTipoLogradouro parte do nome dos tipos de logradouro que se deseja buscar
     * @return List de objetos TipoLogradouro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public List<TipoLogradouroVO> findAllByNome(String dsTipoLogradouro) throws DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TT_TIPOLOGRADOURO WHERE DS_TIPOLOGRADOURO LIKE ? ORDER BY DS_TIPOLOGRADOURO");
        
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            String filtro = "%" + dsTipoLogradouro + "%";
            st.setString(1, filtro);
            
            List<TipoLogradouroVO> listaRegistros = new ArrayList<TipoLogradouroVO>();
            
            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                TipoLogradouroVO tipoLogradouro = new TipoLogradouroVO();
                tipoLogradouro.setIdTipoLogradouro(rs.getInt("ID_TIPOLOGRADOURO"));
                tipoLogradouro.setDsTipoLogradouro(rs.getString("DS_TIPOLOGRADOURO"));
                
                listaRegistros.add(tipoLogradouro);
            }
            st.close();
            rs.close();
            return listaRegistros;
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOTipoLogradouro.findAllByNome()", ex);
        }
    }

    /**
     * Faz o insert de um novo tipoLogradouro e devolve a o id recem gerado
     * @param TipoLogradouro tipoLogradouro que se deseja inserir
     * @return ID auto-increment gerado para esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer insert(TipoLogradouroVO tipoLogradouro) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("INSERT INTO TT_TIPOLOGRADOURO(DS_TIPOLOGRADOURO) ");
        query.append("VALUES (?)");
        
        //retornar id gerado
        Integer generatedId = null;
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, tipoLogradouro.getDsTipoLogradouro());
            
            st.executeUpdate();
            
            //pegar id gerado
            ResultSet rs = st.getGeneratedKeys();
            while (rs.next()) {
                generatedId = new Integer(rs.getString(1));                
            }                    
            
            return generatedId;            
        } catch (SQLException ex) {            
            ex.printStackTrace();
            if (ex.getErrorCode() == 1062) {
                throw new UniqueConstraintException(ex.getMessage(), ex);                
            }
            throw new DatabaseException("Erro no DAOTipoLogradouro.insert()", ex);            
        }      
    }
    
    /**
     * Faz o update de um tipoLogradouro
     * @param TipoLogradouro tipoLogradouro que se deseja alterar
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void update(TipoLogradouroVO tipoLogradouro) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("UPDATE TT_TIPOLOGRADOURO SET DS_TIPOLOGRADOURO = ? ");
        query.append("WHERE ID_TIPOLOGRADOURO = ?");             
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, tipoLogradouro.getDsTipoLogradouro());
            st.setString(2, tipoLogradouro.getIdTipoLogradouro().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOTipoLogradouro.update()", ex);
        }      
    }
    
    /**
     * Faz o delete de um tipoLogradouro
     * @param TipoLogradouro tipoLogradouro que se deseja excluir
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void delete(TipoLogradouroVO tipoLogradouro) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("DELETE FROM TT_TIPOLOGRADOURO ");
        query.append("WHERE ID_TIPOLOGRADOURO = ?");             
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, tipoLogradouro.getIdTipoLogradouro().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOTipoLogradouro.delete()", ex);            
        }      
    }

}
